package io.gitee.kotle.player.ui

import android.app.Activity
import android.content.Context
import android.media.AudioManager
import android.provider.Settings
import android.view.View
import android.view.ViewGroup
import androidx.core.view.children
import io.gitee.kotle.player.R
import io.gitee.kotle.player.core.IPlayer
import kotlin.math.abs

/**
 * 自动管理什么周期
 * 注意自定义View收不到回调的情况，因为onViewAttachedToWindow有延时
 * 可能播放器已经在播放了，view还没有回调
 */
fun <Media, Model : IPlayer.IModel<Media>, Config : IPlayerView.IConfig<Media, Model>> View.bindPlayerView(
    playerConfig: Config,
    immediateAttach: Boolean = false,
    action: ((IPlayerView<Media, Model, Config>, config: Config, attach: Boolean) -> Unit)? = null
) {
    //防止多次回调
    var hadAttach = false
    if (immediateAttach || this.isAttachedToWindow) {
        if (!hadAttach) {
            hadAttach = true
            this.attachPlayerView(playerConfig) { playerView, config ->
                action?.invoke(playerView, config, true)
            }
        }
    }
    this.addOnAttachStateChangeListener(object : View.OnAttachStateChangeListener {
        override fun onViewAttachedToWindow(v: View) {
            if (!hadAttach) {
                hadAttach = true
                this@bindPlayerView.attachPlayerView(playerConfig) { playerView, config ->
                    action?.invoke(playerView, config, true)
                }
            }

        }

        override fun onViewDetachedFromWindow(v: View) {
            if (hadAttach) {
                hadAttach = false
                this@bindPlayerView.detachPlayerView(playerConfig) { playerView, config ->
                    action?.invoke(playerView, config, false)
                }
            }
        }
    })
}

/**
 * 整的顶级父view，将所有子view与[IPlayerView]的管理做处理
 */
fun <Media, Model : IPlayer.IModel<Media>, Config : IPlayerView.IConfig<Media, Model>> View.attachPlayerView(
    config: Config,
    action: ((IPlayerView<Media, Model, Config>, config: Config) -> Unit)? = null
) {
    this.checkIsIPlayerView { playerView ->
        playerView.onPlayerViewConfigCreated(config.player, config)
        if (playerView.needPlayerListener()) {
            config.player.addListener(playerView)
        }
        action?.invoke(playerView, config)
    }
}

/**
 * 整的顶级父view，将所有子view与[IPlayerView]的管理做处理
 * 处理回收
 */
fun <Media, Model : IPlayer.IModel<Media>, Config : IPlayerView.IConfig<Media, Model>> View.detachPlayerView(
    config: Config,
    action: ((IPlayerView<Media, Model, Config>, config: Config) -> Unit)? = null
) {
    this.checkIsIPlayerView<Media, Model, Config, IPlayerView<Media, Model, Config>> { playerView ->
        config.player.removeListener(playerView)
        playerView.onPlayerViewConfigDestroyed(config.player, config)
        action?.invoke(playerView, config)
    }
}

private fun <Media,
        Model : IPlayer.IModel<Media>,
        Config : IPlayerView.IConfig<Media, Model>,
        PlayerView : IPlayerView<Media, Model, Config>> View.checkIsIPlayerView(
    action: ((IPlayerView<Media, Model, Config>) -> Unit)? = null
) {
    if (this is IPlayerView<*, *, *>) {
        action?.invoke(this as PlayerView)
    }
    if (this is ViewGroup) {
        this.children.forEach {
            it.checkIsIPlayerView(action)
        }
    }
}


/**
 * 调节屏幕亮度（0-1.0）
 * percent：亮度新增比例
 * return 当前亮度
 */
internal fun View.setScreenBrightnessSlide(offSet: Float/*每次滑动距离百分比，不是总的滑动距离百分比*/): Float {
    (context as? Activity)?.apply {
        return this.setScreenBrightnessSlide(offSet)
    }
    return 0f
}

internal fun Activity.setScreenBrightnessSlide(offSet: Float): Float {
    val mBrightnessData = getCurrentBrightnessSlide()
    val lpa = window.attributes
    lpa.screenBrightness = mBrightnessData + offSet
    if (lpa.screenBrightness > 1.0f) {
        lpa.screenBrightness = 1.0f
    } else if (lpa.screenBrightness < 0f) {
        lpa.screenBrightness = 0f
    }
    window.attributes = lpa
    return lpa.screenBrightness
}

internal fun Activity.getCurrentBrightnessSlide(): Float {
    var screenBrightness = window.attributes.screenBrightness
    if (screenBrightness < 0f || screenBrightness > 1f) {
        screenBrightness =
            Settings.System.getInt(contentResolver, Settings.System.SCREEN_BRIGHTNESS) / 225f
    }
    return screenBrightness
}


/**
 * 音量调节
 */
internal fun View.setVolume(offSet: Float/*每次滑动距离百分比，不是总的滑动距离百分比*/): Float {
    val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
    val max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
    val saveOffVolume = getTag(R.id.tag_save_current_volume)
    //当前变化的音量
    val offVolume = if (saveOffVolume is Float) {
        saveOffVolume + offSet * max
    } else {
        offSet * max
    }
    val lastVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)

    var newVolume = if (abs(offVolume) > 1f) {
        //变化值已经大于1，可以调节音量
        val split = offVolume.toString().split(".")
        //保存剩余没用消耗值
        setTag(R.id.tag_save_current_volume, "0.${split[1]}".toFloat())
        lastVolume + split[0].toInt()
    } else {
        setTag(R.id.tag_save_current_volume, offVolume)
        lastVolume
    }
    newVolume = when {
        newVolume < 0 -> {
            setTag(R.id.tag_save_current_volume, null)
            0
        }
        newVolume > max -> {
            setTag(R.id.tag_save_current_volume, null)
            max
        }
        else -> {
            newVolume
        }
    }
    if (newVolume != lastVolume) {
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, newVolume, 0)
    }
    return newVolume / max.toFloat()
}
